﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Repository;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Columns;
using DevExpress.XtraGrid.Views.Grid;
using WmsApp.Lookup;
using WmsApp.Report;
using WmsApp.Service;
using WmsApp.UI;
using WmsApp.Window;
using WmsApp.Window.Editor;
using WmsApp.WmsService;
using WmsApp.WindowControl.PriceAndAmount;
using WmsApp.StaticData;

namespace WmsApp.WindowControl
{
    public class InStoreBillController
    {
        public const decimal StaticTaxRate = (decimal) 0.17;
        public delegate void SumAmountChangedEventHandler();

        public event SumAmountChangedEventHandler SumAmountChanged = null;

        private ControlType _controlType = ControlType.None;
        private InStoreBillWrap _wrap = null;
        private TextEdit inBillIDTextEdit = null;
        private LookUpEdit providerLookUpEdit = null;
        private TextEdit providerNameTextEdit = null;
        private DateEdit billDateDateEdit = null;
        private TextEdit inBillStateDescTextEdit = null;
        private GridControl inBillDtlGridControl = null;
        private LookUpEdit inStoreTypeLookUpEdit = null;
        private GridControl invoiceBillGridControl = null;

        private TextEdit textEditRequisitionNo3 = null;
        private TextEdit textEditPurchaseName3 = null;
        private TextEdit textEditProjectNo3 = null;
        private TextEdit textEditKeeperName3 = null;
        private TextEdit textEditContractNo3 = null;
        private TextEdit textEditCheckerName3 = null;
        private MemoEdit memoEditRemark3 = null;
        private LookUpEdit lookUpEditPurchaseID3 = null;
        private LookUpEdit lookUpEditKeeperID3 = null;
        private LookUpEdit lookUpEditCheckerID3 = null;
        private DateEdit dateEditInBillDate3 = null;
        private ComboBoxEdit comboBoxEditPurchaseID3 = null;
        private ComboBoxEdit comboBoxEditKeeperID3 = null;
        private ComboBoxEdit comboBoxEditCheckerID3 = null;

        public ColumnExtraButtonAttacher PColumnExtraButtonAttacher = null;

        #region 构造函数
        public InStoreBillController(TextEdit inBillIDTextEdit, LookUpEdit providerLookUpEdit, TextEdit providerNameTextEdit, DateEdit billDateDateEdit,
            TextEdit inBillStateDescTextEdit, GridControl inBillDtlGridControl, LookUpEdit inStoreTypeLookUpEdit,GridControl invoiceBillGridControl,
                     TextEdit textEditRequisitionNo3,
                     TextEdit textEditPurchaseName3 ,
                     TextEdit textEditProjectNo3 ,
                     TextEdit textEditKeeperName3,
                     TextEdit textEditContractNo3 ,
                     TextEdit textEditCheckerName3 ,
                     MemoEdit memoEditRemark3 ,
                     LookUpEdit lookUpEditPurchaseID3 ,
                     LookUpEdit lookUpEditKeeperID3 ,
                     LookUpEdit lookUpEditCheckerID3 ,
                     ComboBoxEdit comboBoxEditPurchaseID3,
                     ComboBoxEdit comboBoxEditKeeperID3,
                     ComboBoxEdit comboBoxEditCheckerID3,
                     DateEdit  dateEditInBillDate3 )
        {
            CustomInStoreBillId = null;
            //added at 0813
            this.textEditRequisitionNo3 = textEditRequisitionNo3;
            this.textEditPurchaseName3 = textEditPurchaseName3;
            this.textEditProjectNo3 = textEditProjectNo3;
            this.textEditKeeperName3 = textEditKeeperName3;
            this.textEditContractNo3 = textEditContractNo3;
            this.textEditCheckerName3 = textEditCheckerName3;
            this.memoEditRemark3 = memoEditRemark3;
            this.lookUpEditPurchaseID3 = lookUpEditPurchaseID3;
            this.lookUpEditKeeperID3 = lookUpEditKeeperID3;
            this.lookUpEditCheckerID3 = lookUpEditCheckerID3;
            this.dateEditInBillDate3 = dateEditInBillDate3;


            this.inBillDtlGridControl = inBillDtlGridControl;
            this.billDateDateEdit = billDateDateEdit;
            this.inBillIDTextEdit = inBillIDTextEdit;
            this.inBillStateDescTextEdit = inBillStateDescTextEdit;
            this.providerLookUpEdit = providerLookUpEdit;
            this.providerNameTextEdit = providerNameTextEdit;
            this.inStoreTypeLookUpEdit = inStoreTypeLookUpEdit;
            this.invoiceBillGridControl = invoiceBillGridControl;

            this.comboBoxEditPurchaseID3 = comboBoxEditPurchaseID3;
            this.comboBoxEditKeeperID3 = comboBoxEditKeeperID3;
            this.comboBoxEditCheckerID3 = comboBoxEditCheckerID3;

            LookupBind.BindingLookUpEditProvider(this.providerLookUpEdit, providerNameTextEdit);
            LookupBind.BindingLookUpEditInStoreType(this.inStoreTypeLookUpEdit);


        }

        public DateEdit DateEditConfirmInvoiceDate { get; set; }
        public TextEditState TextEditStateConfirmInvoiceFlag { get; set; }
        public TextEdit TextEditConfirmInvoiceID { get; set; }
        public TextEdit TextEditConfirmInvoiceName { get; set; }

        /// <summary>
        /// 绑定grid中的静态数据，注册grid的两个事件
        /// </summary>
        public void BindingStaticData()
        {
            FRepositoryItemGridLookUpEdit =
                LookupBind.BindingLookUpEditGoodsCodeType((GridView)inBillDtlGridControl.MainView,
                ((GridView)inBillDtlGridControl.MainView).Columns.ColumnByFieldName("NewGoodsCode"),
                ((GridView)inBillDtlGridControl.MainView).Columns.ColumnByFieldName("NewGoodsName"),
                ((GridView)inBillDtlGridControl.MainView).Columns.ColumnByFieldName("OldGoodsCode"),
                ((GridView)inBillDtlGridControl.MainView).Columns.ColumnByFieldName("UnitCode"),
                ((GridView)inBillDtlGridControl.MainView).Columns.ColumnByFieldName("UnitName"),
                ((GridView)inBillDtlGridControl.MainView).Columns.ColumnByFieldName("StoreTypeCode"),
                ((GridView)inBillDtlGridControl.MainView).Columns.ColumnByFieldName("StoreTypeName")
                );
            LookupBind.BindingLookUpEditStoreType(
                (GridView)inBillDtlGridControl.MainView,
                ((GridView)inBillDtlGridControl.MainView).Columns.ColumnByFieldName("StoreTypeCode"),
                ((GridView)inBillDtlGridControl.MainView).Columns.ColumnByFieldName("StoreTypeName")
                );

            //LookupBind.BindingLookUpEditSystemUser(this.lookUpEditPurchaseID3, this.textEditPurchaseName3, "PurchaseName");
            //LookupBind.BindingLookUpEditSystemUser(this.lookUpEditKeeperID3, this.textEditKeeperName3, "KeeperName");
            //LookupBind.BindingLookUpEditSystemUser(this.lookUpEditCheckerID3, this.textEditCheckerName3, "CheckerName");

            //add an attacher to the column
            PColumnExtraButtonAttacher = ColumnExtraButtonAttacher.AttachToColumn(FRepositoryItemGridLookUpEdit, (GridView)inBillDtlGridControl.MainView);

            #region Init Control
            //初始化通用公共控件repTextEdit0Dot00           
            this._repTextEdit0Dot00 = new RepositoryItemTextEdit();
            this._repTextEdit0Dot0000 = new RepositoryItemTextEdit();

            this._repTextEdit0Dot00.Name = "repTextEdit0Dot00";
            InitControl(this._repTextEdit0Dot00, "n");

            this._repTextEdit0Dot0000.Name = "repTextEdit0Dot0000";
            InitControl(this._repTextEdit0Dot0000, "n");
            _repTextEdit0Dot0000.DisplayFormat.FormatString = "0.0000";
            _repTextEdit0Dot0000.EditFormat.FormatString = "0.0000";
            #endregion

            ((GridView)inBillDtlGridControl.MainView).CellValueChanged += InStoreBillController_CellValueChanged;
            ((GridView)inBillDtlGridControl.MainView).CustomRowCellEdit += InStoreBillController_CustomRowCellEdit;
        }

        private void InitControl(RepositoryItemTextEdit repTextEdit, string editMask)
        {
            ((System.ComponentModel.ISupportInitialize)(repTextEdit)).BeginInit();
            repTextEdit.AutoHeight = false;
            repTextEdit.DisplayFormat.FormatString = "0.00";
            repTextEdit.DisplayFormat.FormatType = DevExpress.Utils.FormatType.Numeric;
            repTextEdit.EditFormat.FormatString = "0.00";
            repTextEdit.EditFormat.FormatType = DevExpress.Utils.FormatType.Numeric;
            //repTextEdit.Mask.EditMask = "#,##0.00;<<#,##0.00>>";
            repTextEdit.Mask.EditMask = editMask;
            repTextEdit.Mask.MaskType = DevExpress.XtraEditors.Mask.MaskType.Numeric;
            repTextEdit.Mask.UseMaskAsDisplayFormat = true;
            ((System.ComponentModel.ISupportInitialize)(repTextEdit)).EndInit();
        }

        #region 绑定规格型号
        private void InStoreBillController_CustomRowCellEdit(object sender, CustomRowCellEditEventArgs e)
        {
            var gridView = ((GridView) inBillDtlGridControl.MainView);

            //BindingRepositoryItem(e);

            var inStoreBillDtl =(InStoreBillDtl)gridView.GetRow(e.RowHandle);
            if(inStoreBillDtl != null && !String.IsNullOrEmpty(inStoreBillDtl.NewGoodsCode))
            {
                if (e.Column.FieldName == "SpecificationType")
                {
                    var repComboBox = new RepositoryItemComboBox();
                    repComboBox.ReadOnly = false;
                    LookupBind.BindingComboBoxSpecificationTypeItems(repComboBox, inStoreBillDtl.NewGoodsCode);
                    e.RepositoryItem = repComboBox;
                }
            }

            var readOnlyFields = new List<string>();
            readOnlyFields.Add("NewGoodsCode");
            readOnlyFields.Add("StoreTypeCode");
            readOnlyFields.Add("SpecificationType");
            //如果不是新增
            if ( readOnlyFields.Contains( e.Column.FieldName))
            {
                if (inStoreBillDtl.WcfEntityState == EntityState.Added)
                {
                    e.RepositoryItem.ReadOnly = false;
                }
                else
                {
                    e.RepositoryItem.ReadOnly = true;
                }
            }

            //var readOnlyFieldsNumeric = new List<string>();     
            //readOnlyFieldsNumeric.Add("TaxRate");
            //readOnlyFieldsNumeric.Add("PriceTax");
            //readOnlyFieldsNumeric.Add("PriceNotTax");
            //readOnlyFieldsNumeric.Add("AmountTax");
            //readOnlyFieldsNumeric.Add("AmountNotTax");
            //readOnlyFieldsNumeric.Add("Quantity");

            // //如果已经分摊过，则不能修改单价，数量，金额
            //if ((inStoreBillDtl.InvoiceDtlTotalAmountTax ?? 0) > 0)
            //{
            //    if (readOnlyFieldsNumeric.Contains(e.Column.FieldName))
            //    {
            //        e.RepositoryItem.ReadOnly = true;
            //    }
            //}
        }

        #region RepositoryItem 2个

        RepositoryItemTextEdit _repTextEdit0Dot00 = null;
        protected RepositoryItem RepTextEdit0Dot00
        {
            get { return _repTextEdit0Dot00; }
        }

        RepositoryItemTextEdit _repTextEdit0Dot0000 = null;
        protected RepositoryItem RepTextEdit0Dot0000
        {
            get { return _repTextEdit0Dot0000; }
        }
        #endregion

        private void BindingRepositoryItem(CustomRowCellEditEventArgs e)
        {
            var readOnlyFieldsNumeric = new List<string>();
            readOnlyFieldsNumeric.Add("TaxRate");
            readOnlyFieldsNumeric.Add("PriceTax");
            //readOnlyFieldsNumeric.Add("PriceNotTax");
            readOnlyFieldsNumeric.Add("AmountTax");
            readOnlyFieldsNumeric.Add("AmountNotTax");
            readOnlyFieldsNumeric.Add("Quantity");
            if(readOnlyFieldsNumeric.Contains(e.Column.FieldName))
            {
                e.RepositoryItem = this.RepTextEdit0Dot00;
            }
            else if (e.Column.FieldName == "PriceNotTax")
            {
                e.RepositoryItem = this.RepTextEdit0Dot0000;
            }
        }
        #endregion

        #endregion

        /// <summary>
        /// return the RepositoryItemGridLookUpEdit
        /// </summary>
        public RepositoryItemGridLookUpEdit FRepositoryItemGridLookUpEdit{ get; private set; }

        private bool bAutoComputeTax = true;
        /// <summary>
        /// 自动计算含税，不含税，单价，金额，税率等
        /// </summary>
        public bool BAutoComputeTax
        {
            get { return bAutoComputeTax; }
            set { this.bAutoComputeTax = value; }
        }

        #region 含税，不含税，单价，金额，税率等
        private void InStoreBillController_CellValueChanged(object sender, DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs e)
        {
            //如果不是自动计算，但是也得出发事件
            if (!bAutoComputeTax)
            {
                FireSumAmountChangedEvent();
                return;
            }
      
            //31TaxRate32PriceTax33PriceNotTax34AmountTax35AmountNotTax36Quantity
            if (e.Column.FieldName == "TaxRate")
            {
                var value = (decimal)e.Value;
                if (GetValue(e.RowHandle, "PriceTax") > 0 && GetValue(e.RowHandle, "Quantity") > 0)
                {
                    //PriceAndAmountArithBase arith = new PriceAndAmountArithTax(value, GetValue(e.RowHandle, "PriceTax"),
                    //                                        GetValue(e.RowHandle, "Quantity"));
                    var arith = ArithFactory.CreatePriceAndAmountArith(true, value, GetValue(e.RowHandle, "PriceTax"),
                                                            GetValue(e.RowHandle, "Quantity"));
                    SetValue(e.RowHandle, "AmountTax", arith.AmountTax);
                }
                if (GetValue(e.RowHandle, "PriceNotTax") > 0 && GetValue(e.RowHandle, "Quantity") > 0)
                {
                    //PriceAndAmountArithBase arith = new PriceAndAmountArithNotTax(value, GetValue(e.RowHandle, "PriceNotTax"),
                    //                                     GetValue(e.RowHandle, "Quantity"));
                    var arith = ArithFactory.CreatePriceAndAmountArith(false, value, GetValue(e.RowHandle, "PriceNotTax"),
                                        GetValue(e.RowHandle, "Quantity"));
                    SetValue(e.RowHandle, "AmountNotTax", arith.AmountNotTax);
                }
                FireSumAmountChangedEvent();
            }
            else if (e.Column.FieldName == "PriceTax")
            {
                var value = (decimal)e.Value;
                //PriceAndAmountArithBase arith = new PriceAndAmountArithTax(GetValue(e.RowHandle, "TaxRate"), value,
                //                                        GetValue(e.RowHandle, "Quantity"));

                var arith = ArithFactory.CreatePriceAndAmountArith(true, GetValue(e.RowHandle, "TaxRate"), value,
                                                        GetValue(e.RowHandle, "Quantity"));

                SetValue(e.RowHandle, "PriceNotTax", arith.PriceNotTax);
                SetValue(e.RowHandle, "AmountTax", arith.AmountTax);
                SetValue(e.RowHandle, "AmountNotTax", arith.AmountNotTax);
            }
            else if (e.Column.FieldName == "PriceNotTax")
            {
                var value = (decimal)e.Value;
                //PriceAndAmountArithBase arith = new PriceAndAmountArithNotTax(GetValue(e.RowHandle, "TaxRate"), value,
                //                                        GetValue(e.RowHandle, "Quantity"));

                var arith = ArithFactory.CreatePriceAndAmountArith(false, GetValue(e.RowHandle, "TaxRate"), value,
                                                        GetValue(e.RowHandle, "Quantity"));

                SetValue(e.RowHandle, "PriceTax", arith.PriceTax);
                SetValue(e.RowHandle, "AmountTax", arith.AmountTax);
                SetValue(e.RowHandle, "AmountNotTax", arith.AmountNotTax);
                FireSumAmountChangedEvent();
            }
            else if (e.Column.FieldName == "Quantity")
            {
                var value = (decimal)e.Value;
                if (GetValue(e.RowHandle, "PriceTax") > 0 && GetValue(e.RowHandle, "Quantity") > 0)
                {
                    var arith = ArithFactory.CreatePriceAndAmountArith(true, GetValue(e.RowHandle, "TaxRate"),GetValue(e.RowHandle, "PriceTax"), value);
                    SetValue(e.RowHandle, "AmountTax", arith.AmountTax);
                }
                if (GetValue(e.RowHandle, "PriceNotTax") > 0 && GetValue(e.RowHandle, "Quantity") > 0)
                {
                    var arith = ArithFactory.CreatePriceAndAmountArith(false, GetValue(e.RowHandle, "TaxRate"),GetValue(e.RowHandle, "PriceNotTax"), value);
                    SetValue(e.RowHandle, "AmountNotTax", arith.AmountNotTax);
                }
                FireSumAmountChangedEvent();
            }
        }

        private decimal GetValue(int row, string fieldName)
        {
            var gv = (GridView)inBillDtlGridControl.MainView;
            object entity = gv.GetRow(row);
            object obj = entity.GetType().GetProperty(fieldName).GetValue(entity, null);
            return (decimal)obj;
        }

        private void SetValue(int row, string fieldName, decimal value)
        {
            var gv = (GridView)inBillDtlGridControl.MainView;
            object entity = gv.GetRow(row);
            entity.GetType().GetProperty(fieldName).SetValue(entity, value, null);
        }
        #endregion

        public string CurrentBillID
        {
            get { return this._wrap.PInStoreBill.BillID; }
        }

        public string CurrentBillProviderCode
        {
            get { return this._wrap.PInStoreBill.ProviderCode; }
        }

        public CheckEdit CustomInStoreBillId { get; set; }

        private  void FireSumAmountChangedEvent()
        {
            if(SumAmountChanged != null)
            {
                SumAmountChanged();
            }
        }

        /// <summary>
        /// 编辑一个入库单
        /// </summary>
        /// <param name="inStoreBillID"></param>
        public void LoadInStoreBill(string inStoreBillID)
        {
            var service = EntityServiceFactory.GetWrapService<InStoreBillWrap, InStoreBillWrapService>();
            _wrap = service.GetWrap(inStoreBillID);
            _controlType = ControlType.Editing;
            this.DataBinding();
            this.providerLookUpEdit.Properties.ReadOnly = true;
            FireSumAmountChangedEvent();
        }

        /// <summary>
        /// 编辑一个入库单 一个新的入库单
        /// </summary>
        /// <param name="inStoreBill"></param>
        public void LoadInStoreBill(InStoreBillWrap inStoreBill)
        {
            _wrap = inStoreBill;
            _controlType = ControlType.New;
            this.DataBinding();
            this.providerLookUpEdit.Properties.ReadOnly = false;
            FireSumAmountChangedEvent();
        }

        public string BillState
        {
            get { return _wrap.PInStoreBill.BillState; }
        }

        private void DataBinding()
        {
            this.providerLookUpEdit.DataBindings.Clear();
            this.providerLookUpEdit.DataBindings.Add("EditValue", _wrap.PInStoreBill, "ProviderCode");
            this.providerNameTextEdit.DataBindings.Clear();
            this.providerNameTextEdit.DataBindings.Add("EditValue", _wrap.PInStoreBill, "ProviderName");
            this.billDateDateEdit.DataBindings.Clear();
            this.billDateDateEdit.DataBindings.Add("EditValue", _wrap.PInStoreBill, "BillDate");
            this.inBillIDTextEdit.DataBindings.Clear();
            this.inBillIDTextEdit.DataBindings.Add("EditValue", _wrap.PInStoreBill, "BillID");
            this.inBillStateDescTextEdit.DataBindings.Clear();
            this.inBillStateDescTextEdit.DataBindings.Add("EditValue", _wrap.PInStoreBill, "BillStateDesc");

            if(this.TextEditConfirmInvoiceID != null)
            {
                this.TextEditConfirmInvoiceID.DataBindings.Clear();
                this.TextEditConfirmInvoiceID.DataBindings.Add("EditValue", _wrap.PInStoreBill, "ConfirmInvoiceID");
            }

            if (this.TextEditConfirmInvoiceName != null)
            {
                this.TextEditConfirmInvoiceName.DataBindings.Clear();
                this.TextEditConfirmInvoiceName.DataBindings.Add("EditValue", _wrap.PInStoreBill, "ConfirmInvoiceName");
            }

            if (this.DateEditConfirmInvoiceDate != null)
            {
                this.DateEditConfirmInvoiceDate.DataBindings.Clear();
                this.DateEditConfirmInvoiceDate.DataBindings.Add("EditValue", _wrap.PInStoreBill, "ConfirmInvoiceDate",true,DataSourceUpdateMode.OnValidation);
            }

            if (this.TextEditStateConfirmInvoiceFlag != null)
            {
                this.TextEditStateConfirmInvoiceFlag.DataBindings.Clear();
                this.TextEditStateConfirmInvoiceFlag.DataBindings.Add("EditValue", _wrap.PInStoreBill, "ConfirmInvoiceFlag");
            }

            //this.textEditRequisitionNo3 = textEditRequisitionNo3;
            //this.textEditRequisitionNo3.DataBindings.Clear();
            //this.textEditRequisitionNo3.DataBindings.Add("EditValue", wrap.PInStoreBill, "RequisitionNo");
            //this.textEditPurchaseName3 = textEditPurchaseName3;
            //this.textEditPurchaseName3.DataBindings.Clear();
            //this.textEditPurchaseName3.DataBindings.Add("EditValue", wrap.PInStoreBill, "PurchaseName");
            //this.textEditProjectNo3 = textEditProjectNo3;
            this.textEditProjectNo3.DataBindings.Clear();
            this.textEditProjectNo3.DataBindings.Add("EditValue", _wrap.PInStoreBill, "ProjectNo");

            //LookupBind.BindingLookUpEditSystemUser(this.lookUpEditPurchaseID3, this.textEditPurchaseName3, "PurchaseName");
            //LookupBind.BindingLookUpEditSystemUser(this.lookUpEditKeeperID3, this.textEditKeeperName3, "KeeperName");
            //LookupBind.BindingLookUpEditSystemUser(this.lookUpEditCheckerID3, this.textEditCheckerName3, "CheckerName");
            this.comboBoxEditPurchaseID3.DataBindings.Clear();
            this.comboBoxEditPurchaseID3.DataBindings.Add("EditValue", _wrap.PInStoreBill, "PurchaseName");
            this.comboBoxEditCheckerID3.DataBindings.Clear();
            this.comboBoxEditCheckerID3.DataBindings.Add("EditValue", _wrap.PInStoreBill, "CheckerName");
            this.comboBoxEditKeeperID3.DataBindings.Clear();
            this.comboBoxEditKeeperID3.DataBindings.Add("EditValue", _wrap.PInStoreBill, "KeeperName");

            DistinctEntityBinder.BindingComboBoxEdit(comboBoxEditPurchaseID3, "InStoreBill", "PurchaseName");
            DistinctEntityBinder.BindingComboBoxEdit(comboBoxEditCheckerID3, "InStoreBill", "CheckerName");
            DistinctEntityBinder.BindingComboBoxEdit(comboBoxEditKeeperID3, "InStoreBill", "KeeperName");
            //this.textEditKeeperName3 = textEditKeeperName3;
            //this.textEditKeeperName3.DataBindings.Clear();
            //this.textEditKeeperName3.DataBindings.Add("EditValue", wrap.PInStoreBill, "KeeperName");
            //this.textEditContractNo3 = textEditContractNo3;
            this.textEditContractNo3.DataBindings.Clear();
            this.textEditContractNo3.DataBindings.Add("EditValue", _wrap.PInStoreBill, "ContractNo");
            //this.textEditCheckerName3 = textEditCheckerName3;
            //this.textEditCheckerName3.DataBindings.Clear();
            //this.textEditCheckerName3.DataBindings.Add("EditValue", wrap.PInStoreBill, "CheckerName");
            //this.memoEditRemark3 = memoEditRemark3;
            this.memoEditRemark3.DataBindings.Clear();
            this.memoEditRemark3.DataBindings.Add("EditValue", _wrap.PInStoreBill, "Remark");
            //this.lookUpEditPurchaseID3 = lookUpEditPurchaseID3;
            //this.lookUpEditPurchaseID3.DataBindings.Clear();
            //this.lookUpEditPurchaseID3.DataBindings.Add("EditValue", wrap.PInStoreBill, "PurchaseID");
            //this.lookUpEditKeeperID3 = lookUpEditKeeperID3;
            //this.lookUpEditKeeperID3.DataBindings.Clear();
            //this.lookUpEditKeeperID3.DataBindings.Add("EditValue", wrap.PInStoreBill, "KeeperID");
            //this.lookUpEditCheckerID3 = lookUpEditCheckerID3;
            //this.lookUpEditCheckerID3.DataBindings.Clear();
            //this.lookUpEditCheckerID3.DataBindings.Add("EditValue", wrap.PInStoreBill, "CheckerID");
            //this.dateEditInBillDate3 = dateEditInBillDate3;
            this.dateEditInBillDate3.DataBindings.Clear();
            this.dateEditInBillDate3.DataBindings.Add("EditValue", _wrap.PInStoreBill, "InBillDate",true,DataSourceUpdateMode.OnValidation);

            ////由于InBillDate是nullable类型的，所以在绑定的时候，出现问题，现在改造如下：
            //this.dateEditInBillDate3.EditValue = wrap.PInStoreBill.InBillDate;
            //this.dateEditInBillDate3.EditValueChanged += (o, e) =>
            //                                                 {
            //                                                     wrap.PInStoreBill.InBillDate =(DateTime?)this.dateEditInBillDate3.EditValue;
            //                                                 };
            //入库单类型
            if(inStoreTypeLookUpEdit != null)
            {
                this.inStoreTypeLookUpEdit.DataBindings.Clear();
                this.inStoreTypeLookUpEdit.DataBindings.Add("EditValue", _wrap.PInStoreBill, "ExtVarChar1");
            }

            if(_wrap.PInStoreBill.BillState == Constant.BillStateDraft)
            {
                var gv = ((GridView) inBillDtlGridControl.MainView);
                //gv.Columns.ColumnByFieldName("TaxRate").OptionsColumn.AllowEdit = true;
                //gv.Columns.ColumnByFieldName("PriceTax").OptionsColumn.AllowEdit = true;
                //gv.Columns.ColumnByFieldName("PriceNotTax").OptionsColumn.AllowEdit = true;
                //gv.Columns.ColumnByFieldName("Quantity").OptionsColumn.AllowEdit = true;
                //gv.Columns.ColumnByFieldName("NewGoodsCode").OptionsColumn.AllowEdit = true;
                //gv.Columns.ColumnByFieldName("StoreTypeCode").OptionsColumn.AllowEdit = true;
                //gv.Columns.ColumnByFieldName("SpecificationType").OptionsColumn.AllowEdit = true;

                GridColumnAllowEditEnable(gv, "TaxRate", true);
                GridColumnAllowEditEnable(gv, "PriceTax", true);
                GridColumnAllowEditEnable(gv, "PriceNotTax", true);
                GridColumnAllowEditEnable(gv, "Quantity", true);
                GridColumnAllowEditEnable(gv, "NewGoodsCode", true);
                GridColumnAllowEditEnable(gv, "StoreTypeCode", true);
                GridColumnAllowEditEnable(gv, "SpecificationType", true);

                GridColumnAllowEditEnable(gv, "ExtVarChar1", true);
                GridColumnAllowEditEnable(gv, "ExtVarChar2", true);
                //备注
                GridColumnAllowEditEnable(gv, "ExtVarChar4", true);
                GridColumnAllowEditEnable(gv, "ContractDtlNo", true);
            }
            else
            {
                var gv = ((GridView)inBillDtlGridControl.MainView);
                //gv.Columns.ColumnByFieldName("TaxRate").OptionsColumn.AllowEdit = false;
                //gv.Columns.ColumnByFieldName("PriceTax").OptionsColumn.AllowEdit = false;
                //gv.Columns.ColumnByFieldName("PriceNotTax").OptionsColumn.AllowEdit = false;
                //gv.Columns.ColumnByFieldName("Quantity").OptionsColumn.AllowEdit = false;
                //gv.Columns.ColumnByFieldName("NewGoodsCode").OptionsColumn.AllowEdit = false;
                //gv.Columns.ColumnByFieldName("StoreTypeCode").OptionsColumn.AllowEdit = false;
                //gv.Columns.ColumnByFieldName("SpecificationType").OptionsColumn.AllowEdit = false;
                GridColumnAllowEditEnable(gv, "TaxRate", false);
                GridColumnAllowEditEnable(gv, "PriceTax", false);
                GridColumnAllowEditEnable(gv, "PriceNotTax", false);
                GridColumnAllowEditEnable(gv, "Quantity", false);
                GridColumnAllowEditEnable(gv, "NewGoodsCode", false);
                GridColumnAllowEditEnable(gv, "StoreTypeCode", false);
                GridColumnAllowEditEnable(gv, "SpecificationType", false);

                GridColumnAllowEditEnable(gv, "ExtVarChar1", false);
                GridColumnAllowEditEnable(gv, "ExtVarChar2", false);
                //备注
                GridColumnAllowEditEnable(gv, "ExtVarChar4", false);
                GridColumnAllowEditEnable(gv, "ContractDtlNo", false);
            }

            this.inBillDtlGridControl.DataSource = _wrap.PInStoreBillDtl;
            if (invoiceBillGridControl != null)
            {
                this.invoiceBillGridControl.DataSource = _wrap.PInvoiceBillInStoreBill;
            }

            //如果行状态为不为新增状态，则不能修改物料代码

        }

        private void GridColumnAllowEditEnable(GridView gv,string fieldName,bool enabled)
        {
            var gridColumn = gv.Columns.ColumnByFieldName(fieldName);
            if(gridColumn != null)
            {
                gridColumn.OptionsColumn.AllowEdit = enabled;
            }
        }

        public void RemoveInStoreBillDtl(InStoreBillDtl dtl)
        {
            if (_wrap.PInStoreBill.BillState == Constant.BillStateDraft)
            {
                if (dtl.WcfEntityState == EntityState.Added)
                {
                    _wrap.PInStoreBillDtl.Remove(dtl);
                    FireSumAmountChangedEvent();
                    inBillDtlGridControl.RefreshDataSource();
                }
                else
                {
                    try
                    {
                        if (DialogResult.Yes == XtraMessageBox.Show("确实要删除该明细吗？", "提问", MessageBoxButtons.YesNo, MessageBoxIcon.Question))
                        {
                            Factory.WmsServiceFactory.GetServiceClient().DeleteInStoreBillDtl(dtl);
                            _wrap.PInStoreBillDtl.Remove(dtl);
                            FireSumAmountChangedEvent();
                            inBillDtlGridControl.RefreshDataSource();
                        }
                    }
                    catch (Exception ex)
                    {
                        Exceptions.ExceptionHandler.ShowException(ex);
                    }
                 
                }
            }
        }

        /// <summary>
        /// 客户端判断：
        /// 判断是否需要绑定发票，如果配置中存在该入库单类型代码，则不需要，否则需要
        /// </summary>
        /// <returns></returns>
        private bool CheckNeedBindingInvoiceBill()
        {
            if (_wrap == null)
                return false;
            var abnormalInStoreBillCodes = Factory.WmsServiceFactory.GetServiceClient().GetAbnormalInStoreBillCodes();
            var q = from o in abnormalInStoreBillCodes
                    where o.Contains(_wrap.PInStoreBill.ExtVarChar1)
                    select o;
            if (q.Count() > 0)
                return false;
            return true;
        }

        public void AddInvoiceBill()
        {
            if(_wrap == null ||  !this.Save() )
            {
                return;
            }

            if (!CheckNeedBindingInvoiceBill())
            {
                return;
            }

            List<string> invoiceNos = _wrap.PInvoiceBillInStoreBill.Select(invoiceBillInStoreBill => invoiceBillInStoreBill.InvoiceNo).ToList();

            var form = new FormInvoiceBillInStoreBillSelector(_wrap.PInStoreBill.ProviderCode, invoiceNos);
            
            if(DialogResult.OK == form.ShowDialog())
            {
                var list = new List<InvoiceBillInStoreBill>();
                foreach (var invoiceBill in form.FInvoiceBill)
                {
                    var invoiceBillInStoreBill =
                        InvoiceBillInStoreBill.CreateInvoiceBillInStoreBill(invoiceBill.InvoiceNo,
                                                                            _wrap.PInStoreBill.BillID);
                    invoiceBillInStoreBill.PayAmountTax = invoiceBill.PayAmountTax;
                    list.Add(invoiceBillInStoreBill);
                }

                //调用服务器保存
                Factory.WmsServiceFactory.GetServiceClient().AddInvoiceBillInStoreBill(list);
                //刷新
                this.LoadInStoreBill(_wrap.PInStoreBill.BillID);
            }
        }

        public decimal  GetTotalInvoiceBillAmount()
        {
            decimal d1 = _wrap.PInvoiceBillInStoreBill.Sum(o => o.PayAmountTax);
            //decimal d2 = wrap.PInStoreBillDtl.Sum(o => o.AmountTax);
            return d1;
        }

        public decimal GetTotalInStoreBillDtlAmount()
        {
            //decimal d1 = wrap.PInvoiceBillInStoreBill.Sum(o => o.PayAmountTax);
            decimal d2 = _wrap.PInStoreBillDtl.Sum(o => o.AmountTax);
            return d2;
        }

        public void AddInStoreBillDtl()
        {
            if (_wrap != null)
            {
                if(_wrap.PInStoreBill.BillState!= Constant.BillStateDraft)
                {
                    XtraMessageBox.Show( "非草稿状态下不能添加明细！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                int idx = 0;
                if (_wrap.PInStoreBillDtl.Count > 0)
                {
                    idx = _wrap.PInStoreBillDtl.Select(e => e.Idx).Max();
                }
                var dtl = InStoreBillDtl.CreateInStoreBillDtl(_wrap.PInStoreBill.BillID);
                dtl.Idx = idx + 1;
                _wrap.PInStoreBillDtl.Add(dtl);
                this.inBillDtlGridControl.RefreshDataSource();
                FireSumAmountChangedEvent();
            }
        }

        public void AddInStoreBillDtl(List<InStoreBillDtl> list)
        {
            if (_wrap != null)
            {
                if (_wrap.PInStoreBill.BillState != Constant.BillStateDraft)
                {
                    XtraMessageBox.Show("非草稿状态下不能添加明细！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                int idx = 0;
                if (_wrap.PInStoreBillDtl.Count > 0)
                {
                    idx = _wrap.PInStoreBillDtl.Select(e => e.Idx).Max();
                }
                foreach (var inStoreBillDtl in list)
                {
                    inStoreBillDtl.Idx = ++idx;
                    inStoreBillDtl.BillID = _wrap.PInStoreBill.BillID;
                    _wrap.PInStoreBillDtl.Add(inStoreBillDtl);
                }
                this.inBillDtlGridControl.RefreshDataSource();
                FireSumAmountChangedEvent();
            }
        }

        public void NewInStoreBill()
        {
            if (_wrap != null)
            {
                if (_wrap.IsNeedSaved())
                {
                    if (DialogResult.OK == XtraMessageBox.Show(_wrap.PInStoreBill.BillID + "当前入库单已修改，要保存吗？", "提问", MessageBoxButtons.OKCancel, MessageBoxIcon.Question))
                    {
                        SaveInStoreBill();
                    }
                }
            }
            _wrap = new InStoreBillWrap();
            _wrap.PInStoreBill = InStoreBill.CreateInStoreBill();
            _wrap.PInStoreBillDtl = new List<InStoreBillDtl>();
            _wrap.PInvoiceBillInStoreBill = new List<ExtendInvoiceBillInStoreBill>();
            _controlType = ControlType.New;
            this.DataBinding();
            this.providerLookUpEdit.Properties.ReadOnly = false;
            FireSumAmountChangedEvent();
        }

        private bool Save()
        {
            if (_wrap != null && _wrap.PInStoreBill != null)
            {
                if(String.IsNullOrEmpty(_wrap.PInStoreBill.ProviderCode))
                {
                    XtraMessageBox.Show("请选择供应商！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return false;
                }

                //先校验出库单明细
                string msg = string.Empty;
                bool b = ValidateInStoreBillDtl(out msg);
                if(!b)
                {
                    XtraMessageBox.Show(msg, "错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return false;
                }

                if (_wrap.PInStoreBill.WcfEntityState == EntityState.Added)
                {
                    //取号
                    string billID = String.Empty;
                    if(this.CustomInStoreBillId.Checked)
                    {
                        var form = new FormInputId();
                        form.Label = "入库单号码(大于5)：";
                        form.ValidateInputId += (string v,out string m) =>
                                                    {
                                                        m = "";
                                                        var list = Factory.WmsServiceFactory.GetServiceClient().
                                                            GetInStoreBillsByCondition(String.Format(" and BillID='{0}'",v));
                                                        if (list.Count > 0)
                                                        {
                                                            m = "该入库单号已经存在！";
                                                            return false;
                                                        }
                                                        return true;
                                                    };
                        if(DialogResult.OK == form.ShowDialog())
                        {
                            billID = form.InputId;
                        }
                        else
                        {
                            return false;
                        }
                    }
                    else
                    {
                         billID = Factory.WmsServiceFactory.GetServiceClient().GetInStoreBillID();
                    }
                      
                    _wrap.PInStoreBill.BillID = billID;
                    if (_wrap.PInStoreBillDtl != null && _wrap.PInStoreBillDtl.Count > 0)
                    {
                        foreach (var dtl in _wrap.PInStoreBillDtl)
                        {
                            dtl.BillID = billID;
                        }
                    }
                    try
                    {
                        IWrapService<InStoreBillWrap> wrapService =
                            EntityServiceFactory.GetWrapService<InStoreBillWrap, InStoreBillWrapService>();
                        wrapService.SaveWrap(_wrap);
                    }
                    catch (Exception ex)
                    {
                        Exceptions.ExceptionHandler.ShowException(ex);
                        return false;
                    }
                }
                else
                {
                    try
                    {
                        IWrapService<InStoreBillWrap> wrapService =
                            EntityServiceFactory.GetWrapService<InStoreBillWrap, InStoreBillWrapService>();
                        wrapService.SaveWrap(_wrap);
                    }
                    catch (Exception ex)
                    {
                        Exceptions.ExceptionHandler.ShowException(ex);
                        return false;
                    }
                }
                _controlType = ControlType.Saved; 
                return true;
            }
            return false;
        }

        private  bool ValidateInStoreBillDtl(out string msg)
        {
            msg = String.Empty;
            var query = from d in _wrap.PInStoreBillDtl
                        select new
                                   {
                                       NewGoodsCode = d.NewGoodsCode
                                   };
            //if(wrap.PInStoreBillDtl.Count > query.Distinct().Count())
            //{
            //    msg = "明细中含有重复的新物料代码！";
            //    return false;
            //}
            if (_wrap.PInStoreBillDtl.Any(dtl => String.IsNullOrEmpty(dtl.NewGoodsCode)))
            {
                msg = "明细中的新物料代码请输入完整！";
                return false;
            }
            if (_wrap.PInStoreBillDtl.Count == 0)
            {
                msg = "明细数量不能为零！";
                return false;
            }
            return true;
        }

        public void SaveInStoreBill()
        {
            if (Save())
            {
                XtraMessageBox.Show(_wrap.PInStoreBill.BillID + "保存成功！", "提示", MessageBoxButtons.OK,
                                    MessageBoxIcon.Information);
                LoadInStoreBill(_wrap.PInStoreBill.BillID);
            }
        }

        public void AffirmInStoreBill()
        {
            try
            {
                if (Save())
                {
                    //if (CheckNeedBindingInvoiceBill())
                    //{

                    //    decimal d1 = GetTotalInvoiceBillAmount();
                    //    decimal d2 = GetTotalInStoreBillDtlAmount();

                    //    if (d1 != d2)
                    //    {
                    //        XtraMessageBox.Show("物料含税金额和不等于发票分摊金额之和！", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    //        return;
                    //    }
                    //}

                    var confirm = ControllerFactory.GetConfirmWrap(_wrap.PInStoreBill.InBillDate, ConfirmInOutType.In);
                   
                    //if (DialogResult.OK == XtraMessageBox.Show("确实要确认入库吗？", "提问", MessageBoxButtons.OKCancel, MessageBoxIcon.Question))
                    if (confirm.IsConfirmOk)
                    {
                        if (_wrap.PInStoreBillDtl.Count == 0)
                        {
                            XtraMessageBox.Show("出库单至少需要一条入库物料明细！", "警告", MessageBoxButtons.OK,
                                                MessageBoxIcon.Warning);
                            return;
                        }

                        Factory.WmsServiceFactory.GetServiceClient().AffirmInStoreBill2(_wrap.PInStoreBill.BillID, confirm.ConfirmDate);
                        _controlType = ControlType.Saved;
                        LoadInStoreBill(_wrap.PInStoreBill.BillID);
                    }
                }
            }
            catch (Exception ex)
            {
                Exceptions.ExceptionHandler.ShowException(ex);
            }
        }

        public void AffirmInStoreBillInvoice()
        {
            try
            {
                if (_wrap != null && _wrap.PInStoreBill != null)
                {
                    var confirm = ControllerFactory.GetConfirmWrap(ConfirmInOutType.InInvoiceBill);
                    if (confirm.IsConfirmOk)
                    {
                        Factory.WmsServiceFactory.GetServiceClient().AffirmInStoreBillInvoice(_wrap.PInStoreBill.BillID,
                                                                                              confirm.ConfirmDate);
                        LoadInStoreBill(_wrap.PInStoreBill.BillID);
                    }
                }
            }
            catch (Exception ex)
            {
                Exceptions.ExceptionHandler.ShowException(ex);
            }
        }

        public void DeleteInvoiceBillFromInStoreBill()
        {
            if(invoiceBillGridControl == null)
            {
                return;
            }
            var b =(ExtendInvoiceBillInStoreBill)this.invoiceBillGridControl.MainView.GetRow(
                    ((GridView) this.invoiceBillGridControl.MainView).FocusedRowHandle);
            if(b != null)
            {
                if (DialogResult.OK == XtraMessageBox.Show("确实要排除该发票吗？发票号：" + b.InvoiceNo, "提问", MessageBoxButtons.OKCancel, MessageBoxIcon.Question))
                {
                    try
                    {
                        Factory.WmsServiceFactory.GetServiceClient().CancelInStoreBillFromInvoiceBill(b.InvoiceNo, _wrap.PInStoreBill.BillID);
                        this._wrap.PInvoiceBillInStoreBill.Remove(b);
                        this.invoiceBillGridControl.RefreshDataSource();
                        FireSumAmountChangedEvent();
                        XtraMessageBox.Show("排除发票成功！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    catch (Exception ex)
                    {
                        Exceptions.ExceptionHandler.ShowException(ex);
                    }
                }
            }
        }

        internal void Print()
        {
            if (this._wrap.PInStoreBill != null)
            {
                IReport output = new ReportOutputInStoreBill();
                output.ShowReport(this._wrap.PInStoreBill.BillID);
            }
        }

        public void RefreshInStoreBill()
        {
            if(this._wrap != null && _wrap.PInStoreBill != null)
            {
                this.LoadInStoreBill(this._wrap.PInStoreBill.BillID);
            }
        }

        public  void UpdateProvider()
        {
            if (this._wrap != null && this._wrap.PInStoreBill != null)
            {
                if( this._wrap.PInStoreBill.BillID == Constant.NewInBillId)
                {
                    return;
                }

                var service = EntityServiceFactory.GetWrapService<InStoreBillWrap, InStoreBillWrapService>();

                InStoreBillWrap tmpWrap = service.GetWrap(_wrap.PInStoreBill.BillID);
               
                if (tmpWrap == null || tmpWrap.PInStoreBill == null)
                {
                    return;
                }

                if(tmpWrap.PInStoreBill.BillState != Constant.BillStateDraft)
                {
                    XtraMessageBox.Show("非草稿状态不能修改供应商！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                var service2 = EntityServiceFactory.GetEntityService<InvoiceBillInStoreBillDtl, InvoiceBillInStoreBillDtlService>();

                foreach (var inStoreBillDtl in tmpWrap.PInStoreBillDtl)
                {
                    var list = service2.GetEntityList(string.Format(" and InStoreBillDtlID ='{0}' ", inStoreBillDtl.BillDtlID));
                    if(list.Count >0)
                    {
                        XtraMessageBox.Show("已经关联发票的入库单不能修改供应商！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                }

                //var service3 = EntityServiceFactory.GetEntityService<InvoiceBill, InvoiceBillService>();
                //var inStoreBill = service3.GetEntity(tmpWrap.PInStoreBill.BillID);
                //var inStoreBill = this._wrap.PInStoreBill;

                var saveWrap = new InStoreBillWrap();
                saveWrap.PInStoreBillDtl = new List<InStoreBillDtl>();
                saveWrap.PInvoiceBillInStoreBill = new List<ExtendInvoiceBillInStoreBill>();
                saveWrap.PInStoreBill = this._wrap.PInStoreBill;

                var selectForm = new FormSelectCustomer();
                if(DialogResult.OK == selectForm.ShowDialog())
                {
                    if (saveWrap.PInStoreBill.ProviderCode != selectForm.SelectCustomer.OWNERNO)
                    {
                        saveWrap.PInStoreBill.ProviderCode = selectForm.SelectCustomer.OWNERNO;
                        saveWrap.PInStoreBill.ProviderName = selectForm.SelectCustomer.OWNERNAME;
                        service.SaveWrap(saveWrap);
                        RefreshInStoreBill();
                        XtraMessageBox.Show("修改完成！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                }
            }
        }
    }
}
